package com.dmgis.hndz.common.utils;

import com.dmgis.hndz.pojo.AreaTree;
import com.dmgis.hndz.pojo.DeptTree;
import com.dmgis.hndz.pojo.PersonTree;
import com.dmgis.hndz.pojo.TreeNode;

import java.util.*;
import java.util.stream.Collectors;

public class TreeUtil {

    /**
     * 两层循环实现建树
     *
     * @param areaTree
     * @param deptTreeNodes
     * @param root
     * @param <T>
     * @return
     */
    public <T extends TreeNode> List<AreaTree> build(List<AreaTree> areaTree, List<DeptTree> deptTreeNodes, Object root) {

        List<AreaTree> areaTreeNodes = areaTree.stream().sorted(Comparator.comparing(AreaTree::getCode)).collect(Collectors.toList());

        //先将部门的树上下级构建
        Map<Long, DeptTree> deptMap = new HashMap<>();

        for (DeptTree ita : deptTreeNodes) {
            if (ita.getId() != null) {
                deptMap.put(ita.getId(), ita);
            }
        }
        for (DeptTree itb : deptTreeNodes) {
            if (itb.getParentId() != null && deptMap.get(itb.getParentId()) != null) {
                if (deptMap.get(itb.getParentId()).getChildren() == null) {
                    deptMap.get(itb.getParentId()).setChildren(new ArrayList<>());
                }
                if (!deptMap.get(itb.getParentId()).getChildren().contains(itb)) {
                    deptMap.get(itb.getParentId()).add(itb);
                }
                if (itb.getAreaCode() == null || itb.getAreaCode().isEmpty()) {
                    itb.setAreaCode(deptMap.get(itb.getParentId()).getAreaCode());
                }
            }
        }
        Map<String, List<DeptTree>> areaDeptMap = new HashMap<>();
        for (AreaTree treeNode : areaTreeNodes) {
            areaDeptMap.put(treeNode.getCode(), new ArrayList<DeptTree>());
        }
        Iterator iter = deptMap.keySet().iterator();
        while (iter.hasNext()) {
            String key = iter.next().toString();
            try {
                if (deptMap.get(Long.parseLong(key)).getAreaCode() != null) {
                    if (deptMap.get(Long.parseLong(key)).getAreaCode() != null) {
                        if (key != null) {
                            DeptTree dd = deptMap.get(Long.parseLong(key));
                            String advcode = dd.getAreaCode();
                            if (areaDeptMap.get(advcode) != null)
                                areaDeptMap.get(advcode).add(dd);
                        }
                    }
                }
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
        List<AreaTree> trees = new ArrayList<>();
        Map<Long, AreaTree> areaMap = new HashMap<>();

        for (AreaTree treeNode : areaTreeNodes) {
            areaMap.put(treeNode.getId(), treeNode);
        }

        for (AreaTree it : areaTreeNodes) {
            List<DeptTree> deptListOver = areaDeptMap.get(areaMap.get(it.getId()).getCode());
            for (DeptTree deptTree : deptListOver) {
                if (deptTree.getParentId() == null) {
                    AreaTree ar = new AreaTree();
                    ar.setId(deptTree.getId());
                    ar.setStrId(deptTree.getStrId());
                    ar.setName(deptTree.getName());
                    ar.setCode(deptTree.getAreaCode());
                    ar.setParentId(areaMap.get(it.getId()).getId());
                    ar.setUnitType(deptTree.getUnitType());
                    ar.setChildren(deptTree.getChildren());
                    if (areaMap.get(it.getId()).getChildren() != null) {
                        areaMap.get(it.getId()).add(ar);
                    } else {
                        areaMap.get(it.getId()).setChildren(new ArrayList<>());
                    }
                }
            }
            if (areaMap.get(it.getParentId()) != null) {
                if (areaMap.get(it.getParentId()).getChildren() == null) {
                    areaMap.get(it.getParentId()).setChildren(new ArrayList<>());
                }
                areaMap.get(it.getParentId()).add(it);
            }
        }
        trees.add(areaMap.get(root));
        return trees;
    }

    /**
     * 创建地市-工作单位-人员树构建方法
     *
     * @param areaTree 行政区
     * @param deptTreeNodes 部门
     * @param root
     * @param personTree 人员
     * @return
     */
    public List<AreaTree> build(List<AreaTree> areaTree, List<DeptTree> deptTreeNodes, Long root, List<PersonTree> personTree) {
        // 1. 将人员放入部门的子列表中
        Map<Long, DeptTree> deptMap = deptTreeNodes.stream()
                .filter(dept -> dept.getId() != null)
                .collect(Collectors.toMap(DeptTree::getId, dept -> dept));

        for (PersonTree person : personTree) {
            DeptTree dept = deptMap.get(Long.parseLong(person.getDeptId()));
            if (dept != null) {
                if (dept.getChildren() == null) {
                    dept.setChildren(new ArrayList<>());
                }
                dept.add(person);
            }
        }

        // 2. 将部门的上下级关系构建好，并放入对应的行政区
        Map<Long, DeptTree> deptParentMap = new HashMap<>();
        Map<String, List<DeptTree>> areaDeptMap = new HashMap<>();

        for (DeptTree dept : deptTreeNodes) {
            if (dept.getParentId() != null && deptMap.containsKey(dept.getParentId())) {
                DeptTree parent = deptMap.get(dept.getParentId());
                if (parent.getChildren() == null) {
                    parent.setChildren(new ArrayList<>());
                }
                parent.add(dept);
                deptParentMap.put(dept.getId(), parent);
            }

            // 按地区代码分组
            String areaCode = dept.getAreaCode();
            if (areaCode != null) {
                areaDeptMap.computeIfAbsent(areaCode, k -> new ArrayList<>()).add(dept);
            }
        }

        // 3. 构建行政区树结构，并将部门放入行政区的子列表中
        Map<Long, AreaTree> areaMap = areaTree.stream()
                .collect(Collectors.toMap(AreaTree::getId, treeNode -> treeNode));

        for (AreaTree areaNode : areaTree) {
            List<DeptTree> deptList = areaDeptMap.get(areaNode.getCode());
            if (deptList != null) {
                for (DeptTree dept : deptList) {
                    AreaTree deptNode = new AreaTree();
                    deptNode.setId(dept.getId());
                    deptNode.setStrId(dept.getStrId());
                    deptNode.setName(dept.getName());
                    deptNode.setCode(dept.getAreaCode());
                    deptNode.setParentId(areaNode.getId());
                    deptNode.setUnitType(dept.getUnitType());
                    deptNode.setChildren(dept.getChildren());
                    if (areaNode.getChildren() == null) {
                        areaNode.setChildren(new ArrayList<>());
                    }
                    areaNode.add(deptNode);
                }
            }
            if (areaNode.getParentId() != null && areaMap.containsKey(areaNode.getParentId())) {
                AreaTree parent = areaMap.get(areaNode.getParentId());
                if (parent.getChildren() == null) {
                    parent.setChildren(new ArrayList<>());
                }
                parent.add(areaNode);
            }
        }
        List<AreaTree> trees = new ArrayList<>();
        trees.add(areaMap.get(root));
        return trees;
    }

}
